Skip to content

Python < 3.10 - TypeError: 'staticmethod' object is not callable #2263

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jeertmans opened this issue Dec 10, 2024 · 3 comments
Open

Python < 3.10 - TypeError: 'staticmethod' object is not callable #2263

jeertmans opened this issue Dec 10, 2024 · 3 comments
Labels

Comments

@jeertmans
Copy link

Describe the bug

It looks like ManimGL is no longer compatible with Python < 3.10, as, prior to this Python version, @staticmethod were not regular callable (hence, using them as a wrapper didn't work).

See here https://stackoverflow.com/a/76237739.

Code:

from manimlib import *

Wrong display or Error traceback:

manim_slides/slide/manimlib.py:4: in <module>
    from manimlib import Scene, ThreeDCamera
.venv/lib/python3.9/site-packages/manimlib/__init__.py:12: in <module>
    from manimlib.window import *
.venv/lib/python3.9/site-packages/manimlib/window.py:20: in <module>
    class Window(PygletWindow):
.venv/lib/python3.9/site-packages/manimlib/window.py:117: in Window
    def on_mouse_motion(self, x: int, y: int, dx: int, dy: int) -> None:
E   TypeError: 'staticmethod' object is not callable

Additional context

See:

Static methods (@staticmethod) and class methods (@classmethod) now inherit the method attributes (module, name, qualname, doc, annotations) and have a new wrapped attribute. Moreover, static methods are now callable as regular functions. (Contributed by Victor Stinner in bpo-43682.)

from https://docs.python.org/3/whatsnew/3.10.html

@jeertmans jeertmans added the bug label Dec 10, 2024
@quyc666
Copy link

quyc666 commented Dec 25, 2024

I encountered the same problem, Python version is 3.9

@Crazy-lxy
Copy link

I encountered the same problem, Python version is 3.9.5
屏幕截图 2024-12-28 103712

@azerty-svg
Copy link

Guido:

I thought those are callable already.

Me too, but hey, static methods and class methods are weird!

$ python3
Python 3.9.2 (default, Feb 20 2021, 00:00:00) 
>>> def func(): pass
... 
>>> wrapper = classmethod(func)
>>> wrapper()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'classmethod' object is not callable

It's only callable when it goes throught the descriptor!

Found in the gh discussion acout "making classmethods callable"

I found something curious while experimenting with types tonight.

Everybody knows, if you access a descriptor in a class through the normal attribute-getting methods, you actually get the result of calling its 'get' method. If you want to get your hands on the descriptor itself, you can be sneaky and pull it out through the class's dict.

I did an experiment tonight, accessing a bunch of methods in a bunch of different ways.

The methods I tried were

* an instance method,

* a class method, and

* a static method.

I accessed them

* as an instance attribute,

* as a class attribute, and

* through the class __dict__.

And for each of the above, I tried

* one user method and

* one built-in method.

That's a total of eighteen methods tried (3x3x2).

For each one, I printed out whether or not it was callable. I found the results startling: fifteen were, but three (!) were not.

All three that weren't were accessed through the class dict. They were:

* Class method, from builtin class ( dict.__dict__['fromkeys'] )

* Static method, from user class

* Static method, from builtin class ( str.__dict__['maketrans'] )

I find it strange that the static method descriptors aren't callable. I find it even stranger that one of the class method descriptors isn't callable, but the other one is.

I guess a foolish consistency is the hobgoblin of my small mind, but... shouldn't all eighteen of these objects be callable?

Attached is the test harness I wrote.

(p.s. I attached you guys as nosy because I thought you might be interested.)

The above is a python issue from 2014 (Python 3.3)

What does the error you have encountered means? It means, that, in python < 3.10 ; calling

`
def a_func():
pass

a_func = staticmethod(a_func)
`
raised an error

While it should ha been equivalent to:
`
@staticmethod
def a_func():
pass

`
I looked the class hierarchy above Window(PygletWindow) and their's pretty weird stuff happening, with higher-order functions,
dummy functions, function re-assignation etc. It wouldn't surprise me if this stuff lead to calling staticmethod() outside of a
descriptor, which in python <3.10 raised an error (and this error, considered a python bug, was fixed in python 3.10)

So:

  • I suspect the error is caused by class inheritance stuff in our case
  • The error is caused by a python bug
  • The error should no longer appear in python >= 3.10

What's to do:

  • The error is a Python one so it can't be fixed
  • Python-version >= 3.10 should be added to the dependencies of manimlib

I think the case is close

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants